//package elastic.searchCheck;
//
//import com.alibaba.fastjson.JSONArray;
//import com.alibaba.fastjson.JSONObject;
//import com.css.sword.knowing.search.comm.SearchConst;
//import css.sword.util.RedisDao;
//import css.sword.util.StringUtils;
//import elastic.service.SearchService;
//import elastic.util.SearchQueryMap;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.jdbc.core.BatchPreparedStatementSetter;
//import org.springframework.jdbc.core.JdbcTemplate;
//import org.springframework.jdbc.core.PreparedStatementSetter;
//import org.springframework.stereotype.Component;
//import org.tukaani.xz.check.Check;
//
//import java.math.BigDecimal;
//import java.sql.PreparedStatement;
//import java.sql.SQLException;
//import java.text.SimpleDateFormat;
//import java.util.*;
//
///**
// * @author Jeffrey
// * @version 1.0
// * @project 深圳OA
// * @package elastic.searchCheck
// * @file 创建时间:2018/9/15 10:35
// * @title 标题（要求能简洁地表达出类的功能和职责）
// * @description 描述（简要描述类的职责、实现方式、使用注意事项等）
// * @copyright Copyright (c) 2018 中国软件与技术服务股份有限公司
// * @company 中国软件与技术服务股份有限公司
// * @module 模块: 模块名称
// * @reviewer 审核人
// * @history 修订历史（历次修订内容、修订人、修订时间等）
// */
//@Component
//public class CheckTask {
//
//    @Autowired
//    RedisDao redisDao;
//
//    @Autowired
//    JdbcTemplate jdbcTemplate4SearchCheck;
//
//    @Autowired
//    SearchService searchService;
//
//    /**
//     * 分页，每页条数
//     */
//    private static final int PAGE_NUM = 500;
//
//    /**
//     * 针对每一个业务类型，检查每一天的数据
//     *
//     * @param operation 操作类型
//     */
//    public void searchCheck(String operation) {
//        // 取业务类型
//        String service_type = redisDao.popHeadOfList(CheckConstant.REDIS_SERVICE_TYPE_ALL);
//        if (StringUtils.isEmpty(service_type)) {
//            return;
//        }
//
//        // 取要核对的日期
//        String date_prev = CheckUtil.getPrevDate();
//
//        searchCheck(operation, service_type, date_prev);
//    }
//
//    /**
//     * 数据核对，先对数量，数量不一致再对id
//     *
//     * @param operation    操作类型
//     * @param service_type 业务类型
//     * @param date    核对日期
//     */
//    public void searchCheck(String operation, String service_type, String date) {
//        // 要核对的日期
//        String date_condition = " trunc(xgrq) = to_date('" + date + "', 'yyyy-mm-dd')";
//        Calendar calendar_start = Calendar.getInstance();
//
//        // 对比数量
//        long es_data_count = getEsDataCount(service_type, date);
//        long db_data_count = getDbDataCount(service_type, date_condition);
//        if (es_data_count == db_data_count) {
//            String check_status = "0";
//            saveCheck(operation, service_type, date, db_data_count, es_data_count, calendar_start, check_status);
//        } else {
//
//            // 核对数量不相等
//            String check_status = "1";
//
//            // 查询数据库 id 和 es 中 id，存入redis
//            queryEsData(es_data_count, service_type, date);
//            queryDbData(db_data_count, service_type, date, date_condition);
//
//            // 保存到对账表
//            String check_id = saveCheck(operation, service_type, date, db_data_count, es_data_count, calendar_start, check_status);
//
//            // 找es id 和数据库 id 的差集，保存到对账明细表，删除es键
//            handleCheckErrorDetail(service_type, date, check_id);
//        }
//    }
//
//    private JSONObject fetchResult(JSONObject jsonObject) {
//        if (!SearchQueryMap.isEmpty(jsonObject)) {
//
//            Integer code = jsonObject.getInteger("code");
//            if (0 == code) {
//                JSONObject result = jsonObject.getJSONObject("data");
//                if (!SearchQueryMap.isEmpty(result)) {
//
//                    return result.getJSONObject("searchResult");
//                }
//            }
//        }
//
//        return null;
//    }
//
//    /**
//     * 查询es数据量
//     *
//     * @param service_type 业务类型
//     * @param date    日期
//     * @return 数量
//     */
//    private long getEsDataCount(String service_type, String date) {
//        JSONObject jsonObject = getEsResult(service_type, date, 0, 1);
//
//        JSONObject result = fetchResult(jsonObject);
//
//        return SearchQueryMap.isEmpty(result) ? -1 : result.getLong("total");
//    }
//
//    /**
//     * 查询es数据
//     *
//     * @param data_count   数据量
//     * @param service_type 业务类型
//     * @param date    日期
//     */
//    private void queryEsData(long data_count, String service_type, String date) {
//        // 分页查询
//        int page_start = 0;
//        while (page_start < data_count) {
//            int page_end = page_start + PAGE_NUM;
//            queryEsDataWithPage(service_type, date, page_start, PAGE_NUM);
//
//            page_start = page_end;
//        }
//    }
//
//    /**
//     * es查询，并保存到redis
//     *
//     * @param service_type 业务类型
//     * @param date    日期
//     * @param from         分页
//     * @param size         分页
//     */
//    private void queryEsDataWithPage(String service_type, String date, int from, int size) {
//        JSONObject jsonObject = getEsResult(service_type, date, from, size);
//        String[] ids = null;
//
//        JSONObject result = fetchResult(jsonObject);
//        if (!SearchQueryMap.isEmpty(result)) {
//            JSONArray docs = result.getJSONArray("docs");
//
//            if (!SearchQueryMap.isEmpty(docs)) {
//                int length = docs.size();
//                ids = new String[length];
//
//                for (int i = 0; i < length; i++) {
//                    JSONObject doc = docs.getJSONObject(i);
//
//                    ids[i] = doc.getString("_id");
//                }
//            }
//        }
//
//        String redisKey = getRedisKey4Es(service_type, date);
//        redisDao.addToSet(redisKey, ids);
//    }
//
//    /**
//     * es查询
//     *
//     * @param service_type 业务类型
//     * @param date    日期
//     * @param from         分页
//     * @param size         分页
//     * @return
//     */
//    private JSONObject getEsResult(String service_type, String date, int from, int size) {
//        String date_start = date + " 00:00:00";
//        String date_end = CheckUtil.getNextDate(date) + " 00:00:00";
//
////        //普通字段
////        SearchQueryMap.setFieldMap(whereMap, "dblx_dm", "01", null, null);
//        //范围查询
//        final Map<String, Object> whereMap = new HashMap<String, Object>();
//        SearchQueryMap.setRangeFieldMap(whereMap, "xgrq", SearchConst.COMPARISON_OP_GTE, date_start, SearchConst.COMPARISON_OP_LT, date_end, null);
//        String query = SearchQueryMap.getJSONString(whereMap);
//
//        String result = searchService.search(service_type, query, "_id", null, from, size, null, null, null);
//        JSONObject jsonObject = JSONObject.parseObject(result);
//
//        return jsonObject;
//    }
//
//    /**
//     * 查询数据库数据量
//     *
//     * @param service_type   业务类型
//     * @param date_condition 日期条件
//     * @return 数量
//     */
//    private long getDbDataCount(String service_type, String date_condition) {
//        Map<String, String> table_map = redisDao.getMap(CheckConstant.REDIS_SERVICE_TYPE_PREFIX + service_type);
//        String table_name = table_map.get("table");
//        String yxbz = table_map.get("yxbz");
//
//        // 拼接sql
//        StringBuffer sql = new StringBuffer("SELECT count(1) AS count FROM ");
//        sql.append(table_name);
//        sql.append(" WHERE ");
//        sql.append(date_condition);
//        if (StringUtils.isNotEmpty(yxbz)) {
//            sql.append(" AND ").append(yxbz).append(" = 'Y'");
//        }
//        Map<String, Object> data = jdbcTemplate4SearchCheck.queryForMap(sql.toString());
//
//        return ((BigDecimal) data.get("count")).longValue();
//    }
//
//    /**
//     * 查询数据库所有id，并存入redis
//     *
//     * @param data_count     数据量
//     * @param service_type   业务类型
//     * @param date      前一天日期
//     * @param date_condition 日期条件
//     */
//    private void queryDbData(long data_count, String service_type, String date, String date_condition) {
//        Map<String, String> table_map = redisDao.getMap(CheckConstant.REDIS_SERVICE_TYPE_PREFIX + service_type);
//        String table_name = table_map.get("table");
//        String id = table_map.get("id");
//        String yxbz = table_map.get("yxbz");
//
//        // 拼接sql
//        StringBuffer base_sql = new StringBuffer("SELECT ");
//        base_sql.append(id);
//        base_sql.append(" AS id FROM ");
//        base_sql.append(table_name);
//        base_sql.append(" WHERE ");
//        base_sql.append(date_condition);
//        if (StringUtils.isNotEmpty(yxbz)) {
//            base_sql.append(" AND ").append(yxbz).append(" = 'Y'");
//        }
//
//        // 开始查询，分页或不分页
//        if (data_count <= PAGE_NUM) {
//            queryDbDataWithPage(base_sql.toString(), service_type, date);
//        } else {
//
//            // 分页查询
//            int page_start = 0;
//            while (page_start < data_count) {
//                int page_end = page_start + PAGE_NUM;
//                String sql = "SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (" + base_sql + ") A WHERE ROWNUM <= " + page_end + ") WHERE RN > " + page_start;
//                queryDbDataWithPage(sql, service_type, date);
//
//                page_start = page_end;
//            }
//        }
//    }
//
//    /**
//     * 根据sql语句，查询数据库，并将结果保存到redis
//     *
//     * @param sql          sql
//     * @param service_type 业务类型
//     * @param date    前一天日期
//     */
//    private void queryDbDataWithPage(String sql, String service_type, String date) {
//        List<String> data = jdbcTemplate4SearchCheck.queryForList(sql, String.class);
//
//        String redisKey = getRedisKey4Db(service_type, date);
//        redisDao.addToSet(redisKey, data.toArray(new String[data.size()]));
//    }
//
//    /**
//     * 找es id 和数据库 id 的差集，保存到数据库，删除es键
//     *
//     * @param service_type 业务类型
//     * @param date         日期
//     * @param id           主表id
//     */
//    private void handleCheckErrorDetail(String service_type, String date, String id) {
//        String redis_key_db = getRedisKey4Db(service_type, date);
//        String redis_key_es = getRedisKey4Es(service_type, date);
//
//        // 求差集
//        Set<String> es_miss_ids = redisDao.diffOfSet(redis_key_db, redis_key_es);
//        Set<String> db_miss_ids = redisDao.diffOfSet(redis_key_es, redis_key_db);
//
//        // 保存到数据库
//        saveCheckDetail(id, "0", db_miss_ids);
//        saveCheckDetail(id, "1", es_miss_ids);
//
//        // 删除redis键
//        redisDao.deleteKey(redis_key_db);
//        redisDao.deleteKey(redis_key_es);
//    }
//
//    /**
//     * 保存对比结果到数据库
//     *
//     * @param operation    操作类型
//     * @param service_type 业务类型
//     * @param date         核对日期
//     * @param db_count     数据库数量
//     * @param es_count     es数量
//     * @param start        开始时间
//     * @param status       核对状态
//     */
//    private String saveCheck(String operation, String service_type, String date, long db_count, long es_count, Calendar start, String status) {
//
//        // 开始时间
//        java.sql.Date check_start = new java.sql.Date(start.getTime().getTime());
//
//        // 结束时间和耗时
//        Calendar calendar_end = Calendar.getInstance();
//        java.sql.Date check_end =  new java.sql.Date(calendar_end.getTime().getTime());
//        long check_spend = calendar_end.getTimeInMillis() - start.getTimeInMillis();
//
//        // 核对日期
//        java.sql.Date check_date = CheckUtil.convertUtilDate2SqlDate(CheckUtil.convertString2Date(date));
//
//        // 保存
//        String id = UUID.randomUUID().toString().replace("-", "").toLowerCase();
//        String sql = "insert into oa_zh.zh_es_check(hdid, czlx, ywlx, hdrq, sjksl, essl, kssj, jssj, hdhs, hdzt, lrr_dm, lrrq) values (?,?,?,?,?,?,?,?,?,?,?,?)";
//        jdbcTemplate4SearchCheck.update(sql, new PreparedStatementSetter(){
//
//            @Override
//            public void setValues(PreparedStatement preparedStatement) throws SQLException {
//                preparedStatement.setString(1, id);
//                preparedStatement.setString(2, operation);
//                preparedStatement.setString(3, service_type);
//                preparedStatement.setDate(4, check_date);
//                preparedStatement.setLong(5, db_count);
//                preparedStatement.setLong(6, es_count);
//                preparedStatement.setDate(7, check_start);
//                preparedStatement.setDate(8, check_end);
//                preparedStatement.setLong(9, check_spend);
//                preparedStatement.setString(10, status);
//                preparedStatement.setString(11, "00000000000");
//                preparedStatement.setDate(12, CheckUtil.convertUtilDate2SqlDate(new Date()));
//            }
//        });
//
//        return id;
//    }
//
//    /**
//     * 保存到错误明细表，批量操作
//     *
//     * @param id       主表id
//     * @param type     错误类型
//     * @param miss_ids 缺失id
//     */
//    private void saveCheckDetail(String id, String type, Set<String> miss_ids) {
//        String[] miss_id_array = miss_ids.toArray(new String[miss_ids.size()]);
//
//        String sql = "insert into oa_zh.zh_es_check_detail(hdmxid, hdid, cwlx, cwid, clsj, clzt, lrr_dm, lrrq) values (?,?,?,?,?,?,?,?)";
//        jdbcTemplate4SearchCheck.batchUpdate(sql, new BatchPreparedStatementSetter() {
//
//            @Override
//            public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
//                if (StringUtils.isNotEmpty(miss_id_array[i])) {
//                    String detail_id = UUID.randomUUID().toString().replace("-", "").toLowerCase();
//                    preparedStatement.setString(1, detail_id);
//                    preparedStatement.setString(2, id);
//                    preparedStatement.setString(3, type);
//                    preparedStatement.setString(4, miss_id_array[i]);
//                    preparedStatement.setString(5, "");
//                    preparedStatement.setString(6, "");
//                    preparedStatement.setString(7, "00000000000");
//                    preparedStatement.setDate(8, CheckUtil.convertUtilDate2SqlDate(new Date()));
//                }
//            }
//
//            @Override
//            public int getBatchSize() {
//                return miss_ids.size();
//            }
//        });
//    }
//
//    /**
//     * redis键值，数据库所有id
//     *
//     * @param service_type 业务类型
//     * @param date         日期
//     * @return key
//     */
//    private String getRedisKey4Db(String service_type, String date) {
//        return CheckConstant.REDIS_DB_ALL_ID_PREFIX + service_type + ":" + date;
//    }
//
//    /**
//     * redis键值，es所有id
//     *
//     * @param service_type 业务类型
//     * @param date         日期
//     * @return key
//     */
//    private String getRedisKey4Es(String service_type, String date) {
//        return CheckConstant.REDIS_ES_ALL_ID_PREFIX + service_type + ":" + date;
//    }
//}
